/*
* ============================================================================
*  Name     : HttpModule.h
*  Part of  : GV60
*  Copyright: Wipo Software
* ============================================================================
*/

#ifndef __HttpModule_H__
#define __HttpModule_H__

#include <coecntrl.h>
#include <http\mhttpdatasupplier.h>
#include <http\mhttptransactioncallback.h>
#include <http\mhttpauthenticationcallback.h>
#include <es_sock.h>

#define MAX_HTTP_COUNT   100

// Forward declarations
class RHTTPSession;
class RHTTPTransaction;
class RSocketServ;
class RConnection;

class MHttpModuleObserver
{
  public:
    virtual void HttpResult(TInt iStatusCode, const TDesC8& n_iResult) = 0;
};

class CHttpCollection
{
  public:
    CHttpCollection();
    ~CHttpCollection();
  
  public:
    void Reset();
    inline TInt Count() { return m_iCount; };

    void Set(const TDesC8& iName, const TDesC8& iValue);
    const TDesC8& Get(const TDesC8& iName);
    void Remove(const TDesC8& iName);
    const TDesC8& GetName(TInt iCount);
    const TDesC8& GetValue(TInt iCount);
    
  private:
    TInt      m_iCount;
    HBufC8*   m_pName[MAX_HTTP_COUNT];
    HBufC8*   m_pValue[MAX_HTTP_COUNT];
};

class CHttpHeaderCollection : public CHttpCollection
{
  public:
    inline void SetHeader(const TDesC8& iName, const TDesC8& iValue) { Set(iName, iValue); }
    inline const TDesC8& GetHeader(const TDesC8& iName)              { return Get(iName); }
    inline void RemoveHeader(const TDesC8& iName)                    { Remove(iName); }
    inline void SetStatusCode(TInt iStatusCode)                      { m_iStatusCode = iStatusCode; };
    inline TInt GetStatusCode()                                      { return m_iStatusCode; };
    inline void Reset()                                              { m_iStatusCode = 0; CHttpCollection::Reset(); }

  private:
    TInt    m_iStatusCode;
};

// Provides simple interface to HTTP Client API.
class CHttpModule : public CActive,
                    public MHTTPTransactionCallback, public MHTTPDataSupplier,
                    public MHTTPAuthenticationCallback
{
  public:
    static CHttpModule* NewL(MHttpModuleObserver* n_pObserver, TUint32 n_iap = 0 );
    static CHttpModule* NewLC(MHttpModuleObserver* n_pObserver, TUint32 n_iap = 0 );
    ~CHttpModule();

    void SetAuthentication(const TDesC8& aUsername, const TDesC8& aPassword);
    TInt IssueHTTPGetL(const TDesC8& aUri, TInt iMaxTimer = 0, CHttpHeaderCollection* pHeaders = NULL);
    TInt IssueHTTPPostL(const TDesC8& aUri, const TDesC8& aContentType, const TDesC8& aBody, TInt iMaxTimer = 0, CHttpHeaderCollection* pHeaders = NULL);
    void CancelTransaction();
    inline TBool IsRunning() { return m_bRunning; };

    static TUint32 ConnectionNameToIap(const TDesC8& aConnectionName);

  private:
    CHttpModule();
    void ConstructL(MHttpModuleObserver* n_pObserver, TUint32 n_iap);

  private: // From CActive
    void RunL();
    void DoCancel();

  private: // From MHTTPSessionEventCallback
    void MHFRunL(RHTTPTransaction aTransaction, const THTTPEvent& aEvent);
    TInt MHFRunError(  TInt aError, RHTTPTransaction aTransaction, const THTTPEvent& aEvent);

  private: // From MHTTPDataSupplier (needed for HTTP POST)
    void  ReleaseData();
    TBool GetNextDataPart(TPtrC8& aDataPart);
    TInt  Reset();
    TInt  OverallDataSize();

  private: // From MHTTPAuthenticationCallback (needed for HTTP authentication)
    TBool GetCredentialsL(const TUriC8& aURI, RString aRealm, RStringF aAuthenticationType, RString& aUsername, RString& aPassword);
  
  private: // New methods
    void  StartTimerL(TInt iMaxTimer);
    void  StopTimer();
    void  SetHeaderL(RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue);
    void  SetCookiesL(RHTTPHeaders aHeaders);
    void  GetCookiesL(RHTTPTransaction& aTransaction);
    void  StopTransaction();
    void  ExecuteCallback();

    static TInt HttpTimerCallBack(TAny *aPtr);
    void  DoHttpTimerCallback();

  private:
    MHttpModuleObserver*        m_pObserver;        // Observer
    
    RHTTPSession                m_iSession;
    RHTTPTransaction            m_iTransaction;
    RSocketServ                 m_iSockServ;
    RConnection                 m_iConnection;
    
    CPeriodic*                  m_pHttpTimer;        // Http timer
    TBool                       m_bRunning;          // ETrue, if transaction running

    HBufC8*                     m_pPostData;         // Data for HTTP POST
    TInt                        m_iStatusCode;
    HBufC8*                     m_pResponseBody;     // Buffer with content from server
    TInt                        m_iHttpAttempt;      // Number of attempts (authentications, contents moved, ...)
    CHttpHeaderCollection*      m_pHeaderCollection; // Pointer to header collection

    HBufC8*                     m_pUsername;         // Username for authentication
    HBufC8*                     m_pPassword;         // Password for authentication
    
    CHttpCollection             m_iCookieArray;      // Array for cookies
};

#endif // __HttpModule_H__
